/**
 * @fileOverview
 */

Karamu = Karamu || {};
Karamu.Controllers = Karamu.Controllers || {};

/**
 * Groups are displayed as categories in desktop view; as tabs in dashboard view. Tabs are sub-divided into columns, and
 * gadgets are stacked in the columns.
 *
 * @class
 * @requires jQuery, underscore.js, karamu.js
 * @param {Object} context the top-level controller object, e.g karamu
 */
Karamu.Controllers.Shortcut = function(context){
    this.context = context;

    /**
     * @param   {Object}    element     the DOM element (group) to append the gadget to
     * @param   {string}    gadget      a plain object
     * @public
     */
    this.render = function(element, data){
        data.height = data.height.length ? data.height : 300;
        data.width  = data.width.length  ? data.width  : 400;
        var shortcut = this.context.tmpl('desktop-gadget-shortcut', data);
        for (i in data) {
            shortcut.data(i, data[i]);
        }
        shortcut.data('groupId', $(element).parents('.group').attr('id').substr('group-'.length));
        shortcut.on({
            click: this.click,
            dragstart: this.dragstart,
            dragend: this.dragend
        }, this);

        // enable drag-n-drop in IE
        if (shortcut[0].dragDrop) {
            shortcut.on({
                mousemove: this.mousemove
            }, this);
        }

        $('.gadget-remove', shortcut).on({
            click: this.removeElement
        }, this);
        $(element).append(shortcut);
    };

    /**
     * @param   {Object}    element     the DOM element (group) to append the gadget to
     * @param   {string}    gadget      a plain object
     * @public
     */
    this.renderSidebar = function(element, data){
        var shortcut = this.context.tmpl('desktop-sidebar-icon', data);
        for (i in data) {
            shortcut.data(i, data[i]);
        }
        shortcut.on({
            click: this.click
        }, this);
        $(element).append(shortcut);
    };

    /**
     * @param {?Object} e event object
     * @public
     */
    this.click = function(e){
        e.preventDefault();

        var data = $(e.currentTarget).data();
        if (console && console.log) console.log('Rendering menu gadget with title "' + data.title + '" and URL "' + data.url + '"');

        e.data.context.controllers.gadget.render(data, e.data.context.controllers.desktop.windowCount);
        e.data.context.controllers.desktop.windowCount++;
    };

    /**
     * @param {?Object} e event object
     * @public
     */
    this.mousemove = function(e) {
        var target = e.target;
        if (window.event.button === 1) {
            target.dragDrop();
        }
    };

    /**
     * @param {?Object} e event object
     * @public
     */
    this.removeElement = function(e) {
        e.preventDefault();

        var el = $($(e.currentTarget).parents(e.data.context.controllers.catalog.options.gadgetSelector)),
            data = el.data();

        // Remove it from the interface
        el.remove();

        // Update the model
        $(e.data.context.models[e.data.context.view]).trigger('remove-shortcut', [data, data.groupId]);
    };

    /**
     * @param {?Object} e event object
     * @public
     */
    this.dragstart = function(e) {
        $(e.data.context.controllers.catalog.options.dropzoneSelector).addClass('glow');
        $(e.currentTarget).css('opacity', 0.5);
        $(e.currentTarget).addClass('dragstart');
        e.originalEvent.dataTransfer.effectAllowed = 'copyMove';
        e.originalEvent.dataTransfer.setData('URL', $(e.currentTarget).data('url'));
        e.originalEvent.dataTransfer.setData('Text', JSON.stringify($(e.currentTarget).data()));
    };

    /**
     * @param {?Object} e event object
     * @public
     */
    this.dragend = function(e) {
        $(e.data.context.controllers.catalog.options.dropzoneSelector).removeClass('glow');
        $(e.currentTarget).css('opacity', 1);
        $(e.currentTarget).removeClass('dragstart');
    };

    /**
     * @param {Object} e event object
     * @param {Object} e.data the top-level controller object, e.g karamu
     * @param {Object} gadget a plain object
     * @param {string} groupId exactly what it sounds like
     * @public
     */
    this.add = function(e, gadget, groupId){
        for (var a = 0, b = e.data.models[e.data.view].groups.length; a < b; a++) {
            if (e.data.models[e.data.view].groups[a].id === groupId) {
                e.data.models[e.data.view].groups[a].gadgets.push(gadget);
                e.data.models[e.data.view].groups[a].gadgets = _.sortBy(e.data.models[e.data.view].groups[a].gadgets, function(g){ return g.title; });
                if (console && console.log) console.log('Gadget "' + gadget.title + '" (' + gadget.id + ') added to group (' + groupId + ').');
                $(e.data.models[e.data.view]).trigger('change-group', groupId);
            }
        }
    };

    /**
     * @param {Object} e event object
     * @param {Object} e.data the top-level controller object, e.g karamu
     * @param {Object} gadget a plain object
     * @param {string} groupId exactly what it sounds like
     * @public
     */
    this.change = function(e, gadgetId, gadgetData, groupId){
        for (var a = 0, b = e.data.models[e.data.view].groups.length; a < b; a++) {
            if (e.data.models[e.data.view].groups[a].id === groupId) {
                for (var c = 0, d = e.data.models[e.data.view].groups[a].gadgets.length; c < d; c++) {
                    if (e.data.models[e.data.view].groups[a].gadgets[c].thumbnail === gadgetData.thumbnail &&
                        e.data.models[e.data.view].groups[a].gadgets[c].title     === gadgetData.title &&
                        e.data.models[e.data.view].groups[a].gadgets[c].url       === gadgetData.url
                    ) {
                        if (gadgetData) {
                            for (f in gadgetData) {
                                e.data.models[e.data.view].groups[a].gadgets[c][f] = gadgetData[f];
                            }
                        }
                        e.data.models[e.data.view].groups[a].gadgets = _.sortBy(e.data.models[e.data.view].groups[a].gadgets, function(g){ return g.title; });
                        if (console && console.log) console.log('Gadget "' + gadgetData.title + '" changed within group (' + groupId + ').');
                        $(e.data.models[e.data.view]).trigger('change-group', groupId);
                    }
                }
            }
        }
    };

    /**
     * @param {Object} e event object
     * @param {Object} e.data the top-level controller object, e.g karamu
     * @param {Object} gadget a plain object
     * @param {string} groupId exactly what it sounds like
     * @public
     */
    this.remove = function(e, gadget, groupId) {
        for (var a = 0, b = e.data.models[e.data.view].groups.length; a < b; a++) {
            if (e.data.models[e.data.view].groups[a].id === groupId) {
                for (var c = 0, d = e.data.models[e.data.view].groups[a].gadgets.length; c < d; c++) {
                    if (e.data.models[e.data.view].groups[a].gadgets[c].thumbnail === gadget.thumbnail &&
                        e.data.models[e.data.view].groups[a].gadgets[c].title     === gadget.title &&
                        e.data.models[e.data.view].groups[a].gadgets[c].url       === gadget.url
                    ) {
                        e.data.models[e.data.view].groups[a].gadgets.splice(c, 1);
                        e.data.models[e.data.view].groups[a].gadgets = _.sortBy(e.data.models[e.data.view].groups[a].gadgets, function(g){ return g.title; });
                        if (console && console.log) console.log('Gadget "' + gadget.title + '" removed from group (' + groupId + ').');
                        $(e.data.models[e.data.view]).trigger('change-group', groupId);
                        d--;
                    }
                }
            }
        }
    };

};